﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using Domain.NetworkService.Behaviors.Interfaces;
using System.ComponentModel;

namespace Domain.NetworkService
{
    public class ResolveTestBehavior : INetworkServiceTest
    {
        private string hostNameOrIP;
        public ResolveTestBehavior(string hostNameOrIP, TimeSpan timeout)
        {
            this.hostNameOrIP = hostNameOrIP;
            this.Timeout = timeout;
            Description = new Description()
            {
                networkTestDescription = NetworkTestDescription.NS,
                Special = Stub.Absent,
                Timeout = timeout,
                HostNameOrIP = hostNameOrIP
            };
        }
        public NetworkTestResult Start()
        {
            // Если в конструкторе передана строка с IP address
            IPAddress tmp;
            if (IPAddress.TryParse(hostNameOrIP, out tmp))
            {
                try
                {
                    hostNameOrIP = Dns.GetHostEntry(hostNameOrIP).HostName;
                }
                catch (SocketException)
                {
                   return new ResolveResult()
                   {
                       Status = ResultStatus.Failed,
                       HostName = hostNameOrIP,
                       VarDateTime = DateTime.Now,
                       Ips = null
                   };
                }
                tmp = null;
            }

            List<IPAddress> ips;
            try
            {
                ips = Dns.GetHostAddresses(hostNameOrIP).ToList<IPAddress>();
            }
            catch (Exception)
            {
                hostNameOrIP = getSecondLevelDomain(hostNameOrIP);
                ips = Dns.GetHostAddresses(hostNameOrIP).ToList<IPAddress>();
            }
            if (ips.Count > 0)
            {
                HashSet<IPAddress> tmpHashSet = new HashSet<IPAddress>(ips);
                return new ResolveResult()
                {
                    Status = ResultStatus.Success,
                    HostName = hostNameOrIP,
                    VarDateTime = DateTime.Now,
                    
                    Ips = tmpHashSet,
                    IP = getIPV4(ips)
                };
            }
            else
            {
                return new ResolveResult()
                {
                    Status = ResultStatus.Failed,
                    IP = IPAddress.None,
                    VarDateTime = DateTime.Now,
                    Ips = null
                };
            }
        }
        private string getSecondLevelDomain(string hostName)
        {
            string[] doms = hostName.Split('.');
            // для abc.mail.ru вернет только mail.ru
            if (doms.Length > 2)
            {
                return String.Format("{0}.{1}", doms[doms.Length - 2], doms[doms.Length - 1]);    
            }
            // для k2-tat-02.sstuedudom
            return doms[0];
        }
        private IPAddress getIPV4(List<IPAddress> ips)
        {
            IPAddress ip = IPAddress.None;

            foreach (var item in ips)
            {
                if (item.AddressFamily.ToString().Equals(AddressFamily.InterNetwork.ToString()))
                {
                    ip = item;
                }
            }
            return ip;
        }
        public IDescription Description { get; set; }
        public TimeSpan Timeout { get; set; }
    }
}
